Fix MCP dep tool parameter names to match CLI (issue_id/depends_on_id)
- Changed from confusing from_id/to_id to clear issue_id/depends_on_id - Matches CLI convention: bd dep add [issue-id] [depends-on-id] - Updated all tests and implementations - Fixes GH #113 where Claude Code was creating dependencies backwards Closes bd-58 Amp-Thread-ID: https://ampcode.com/threads/T-f01aca11-a10f-4908-9ce6-7e1734f2068f Co-authored-by: Amp <amp@ampcode.com>
This commit is contained in:
@@ -498,8 +498,8 @@ class BdCliClient(BdClientBase):
|
||||
self.bd_path,
|
||||
"dep",
|
||||
"add",
|
||||
params.from_id,
|
||||
params.to_id,
|
||||
params.issue_id,
|
||||
params.depends_on_id,
|
||||
"--type",
|
||||
params.dep_type,
|
||||
*self._global_flags(),
|
||||
|
||||
@@ -415,8 +415,8 @@ class BdDaemonClient(BdClientBase):
|
||||
params: Dependency parameters
|
||||
"""
|
||||
args = {
|
||||
"from_id": params.from_id,
|
||||
"to_id": params.to_id,
|
||||
"from_id": params.issue_id,
|
||||
"to_id": params.depends_on_id,
|
||||
"dep_type": params.dep_type or "blocks",
|
||||
}
|
||||
await self._send_request("dep_add", args)
|
||||
|
||||
@@ -97,8 +97,8 @@ class ReopenIssueParams(BaseModel):
|
||||
class AddDependencyParams(BaseModel):
|
||||
"""Parameters for adding a dependency."""
|
||||
|
||||
from_id: str
|
||||
to_id: str
|
||||
issue_id: str
|
||||
depends_on_id: str
|
||||
dep_type: DependencyType = "blocks"
|
||||
|
||||
|
||||
|
||||
@@ -386,15 +386,15 @@ related (soft link), parent-child (epic/subtask), discovered-from (found during
|
||||
)
|
||||
@require_context
|
||||
async def add_dependency(
|
||||
from_id: str,
|
||||
to_id: str,
|
||||
issue_id: str,
|
||||
depends_on_id: str,
|
||||
dep_type: DependencyType = "blocks",
|
||||
workspace_root: str | None = None,
|
||||
) -> str:
|
||||
"""Add a dependency relationship between two issues."""
|
||||
return await beads_add_dependency(
|
||||
from_id=from_id,
|
||||
to_id=to_id,
|
||||
issue_id=issue_id,
|
||||
depends_on_id=depends_on_id,
|
||||
dep_type=dep_type,
|
||||
)
|
||||
|
||||
|
||||
@@ -229,8 +229,8 @@ async def beads_reopen_issue(
|
||||
|
||||
|
||||
async def beads_add_dependency(
|
||||
from_id: Annotated[str, "Issue that depends on another (e.g., bd-2)"],
|
||||
to_id: Annotated[str, "Issue that blocks or is related to from_id (e.g., bd-1)"],
|
||||
issue_id: Annotated[str, "Issue that has the dependency (e.g., bd-2)"],
|
||||
depends_on_id: Annotated[str, "Issue that issue_id depends on (e.g., bd-1)"],
|
||||
dep_type: Annotated[
|
||||
DependencyType,
|
||||
"Dependency type: blocks, related, parent-child, or discovered-from",
|
||||
@@ -239,22 +239,22 @@ async def beads_add_dependency(
|
||||
"""Add a dependency relationship between two issues.
|
||||
|
||||
Types:
|
||||
- blocks: to_id must complete before from_id can start
|
||||
- blocks: depends_on_id must complete before issue_id can start
|
||||
- related: Soft connection, doesn't block progress
|
||||
- parent-child: Epic/subtask hierarchical relationship
|
||||
- discovered-from: Track that from_id was discovered while working on to_id
|
||||
- discovered-from: Track that issue_id was discovered while working on depends_on_id
|
||||
|
||||
Use 'discovered-from' when you find new work during your session.
|
||||
"""
|
||||
client = await _get_client()
|
||||
params = AddDependencyParams(
|
||||
from_id=from_id,
|
||||
to_id=to_id,
|
||||
issue_id=issue_id,
|
||||
depends_on_id=depends_on_id,
|
||||
dep_type=dep_type,
|
||||
)
|
||||
try:
|
||||
await client.add_dependency(params)
|
||||
return f"Added dependency: {from_id} depends on {to_id} ({dep_type})"
|
||||
return f"Added dependency: {issue_id} depends on {depends_on_id} ({dep_type})"
|
||||
except BdError as e:
|
||||
return f"Error: {str(e)}"
|
||||
|
||||
|
||||
@@ -548,7 +548,7 @@ async def test_add_dependency(bd_client, mock_process):
|
||||
mock_process.communicate = AsyncMock(return_value=(b"Dependency added\n", b""))
|
||||
|
||||
with patch("asyncio.create_subprocess_exec", return_value=mock_process):
|
||||
params = AddDependencyParams(from_id="bd-2", to_id="bd-1", dep_type="blocks")
|
||||
params = AddDependencyParams(issue_id="bd-2", depends_on_id="bd-1", dep_type="blocks")
|
||||
await bd_client.add_dependency(params)
|
||||
|
||||
# Should complete without raising an exception
|
||||
@@ -564,7 +564,7 @@ async def test_add_dependency_failure(bd_client, mock_process):
|
||||
patch("asyncio.create_subprocess_exec", return_value=mock_process),
|
||||
pytest.raises(BdCommandError, match="bd dep add failed"),
|
||||
):
|
||||
params = AddDependencyParams(from_id="bd-2", to_id="bd-1", dep_type="blocks")
|
||||
params = AddDependencyParams(issue_id="bd-2", depends_on_id="bd-1", dep_type="blocks")
|
||||
await bd_client.add_dependency(params)
|
||||
|
||||
|
||||
@@ -575,7 +575,7 @@ async def test_add_dependency_not_found(bd_client):
|
||||
patch("asyncio.create_subprocess_exec", side_effect=FileNotFoundError()),
|
||||
pytest.raises(BdNotFoundError, match="bd CLI not found"),
|
||||
):
|
||||
params = AddDependencyParams(from_id="bd-2", to_id="bd-1", dep_type="blocks")
|
||||
params = AddDependencyParams(issue_id="bd-2", depends_on_id="bd-1", dep_type="blocks")
|
||||
await bd_client.add_dependency(params)
|
||||
|
||||
|
||||
|
||||
@@ -255,7 +255,7 @@ async def test_add_dependency(bd_client):
|
||||
issue2 = await bd_client.create(CreateIssueParams(title="Issue 2", priority=1, issue_type="task"))
|
||||
|
||||
# Add dependency: issue2 blocks issue1
|
||||
params = AddDependencyParams(from_id=issue1.id, to_id=issue2.id, dep_type="blocks")
|
||||
params = AddDependencyParams(issue_id=issue1.id, depends_on_id=issue2.id, dep_type="blocks")
|
||||
await bd_client.add_dependency(params)
|
||||
|
||||
# Verify dependency by showing issue1
|
||||
@@ -392,7 +392,7 @@ async def test_dependency_types(bd_client):
|
||||
issue2 = await bd_client.create(CreateIssueParams(title="Issue 2", priority=1, issue_type="task"))
|
||||
|
||||
# Test related dependency
|
||||
params = AddDependencyParams(from_id=issue1.id, to_id=issue2.id, dep_type="related")
|
||||
params = AddDependencyParams(issue_id=issue1.id, depends_on_id=issue2.id, dep_type="related")
|
||||
await bd_client.add_dependency(params)
|
||||
|
||||
# Verify
|
||||
|
||||
@@ -382,7 +382,7 @@ async def test_add_dependency_tool(mcp_client):
|
||||
# Add dependency
|
||||
result = await mcp_client.call_tool(
|
||||
"dep",
|
||||
{"from_id": issue1["id"], "to_id": issue2["id"], "dep_type": "blocks"},
|
||||
{"issue_id": issue1["id"], "depends_on_id": issue2["id"], "dep_type": "blocks"},
|
||||
)
|
||||
|
||||
message = result.content[0].text
|
||||
@@ -523,7 +523,7 @@ async def test_dependency_types(mcp_client):
|
||||
# Test related dependency
|
||||
result = await mcp_client.call_tool(
|
||||
"dep",
|
||||
{"from_id": issue1["id"], "to_id": issue2["id"], "dep_type": "related"},
|
||||
{"issue_id": issue1["id"], "depends_on_id": issue2["id"], "dep_type": "related"},
|
||||
)
|
||||
|
||||
message = result.content[0].text
|
||||
|
||||
@@ -237,7 +237,7 @@ async def test_beads_add_dependency_success():
|
||||
|
||||
with patch("beads_mcp.tools._get_client", return_value=mock_client):
|
||||
result = await beads_add_dependency(
|
||||
from_id="bd-2", to_id="bd-1", dep_type="blocks"
|
||||
issue_id="bd-2", depends_on_id="bd-1", dep_type="blocks"
|
||||
)
|
||||
|
||||
assert "Added dependency" in result
|
||||
@@ -258,7 +258,7 @@ async def test_beads_add_dependency_error():
|
||||
|
||||
with patch("beads_mcp.tools._get_client", return_value=mock_client):
|
||||
result = await beads_add_dependency(
|
||||
from_id="bd-2", to_id="bd-1", dep_type="blocks"
|
||||
issue_id="bd-2", depends_on_id="bd-1", dep_type="blocks"
|
||||
)
|
||||
|
||||
assert "Error" in result
|
||||
|
||||
1694
integrations/beads-mcp/uv.lock
generated
Normal file
1694
integrations/beads-mcp/uv.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user