feat: display external deps in bd dep tree (bd-vks2, bd-mv6h, bd-d9mu)

External dependencies (external:project:capability) are now visible in
the dependency tree output. Previously they were invisible because the
recursive CTE only JOINed against the issues table.

Changes:
- GetDependencyTree now fetches external deps and adds them as synthetic
  leaf nodes with resolution status (satisfied/blocked)
- formatTreeNode displays external deps with special formatting
- Added helper parseExternalRefParts for parsing external refs

Test coverage added for:
- External deps appearing in dependency tree
- Cycle detection ignoring external refs
- CheckExternalDep when target has no .beads directory
- Various invalid external ref format variations

Closes: bd-vks2, bd-mv6h, bd-d9mu
This commit is contained in:
Steve Yegge
2025-12-22 22:34:03 -08:00
parent 73b2e14919
commit ad02b80330
4 changed files with 373 additions and 0 deletions

View File

@@ -639,6 +639,21 @@ func (r *treeRenderer) renderNode(node *types.TreeNode, children map[string][]*t
// formatTreeNode formats a single tree node with status, ready indicator, etc.
func formatTreeNode(node *types.TreeNode) string {
// Handle external dependencies specially (bd-vks2)
if IsExternalRef(node.ID) {
// External deps use their title directly which includes the status indicator
var idStr string
switch node.Status {
case types.StatusClosed:
idStr = ui.StatusClosedStyle.Render(node.Title)
case types.StatusBlocked:
idStr = ui.StatusBlockedStyle.Render(node.Title)
default:
idStr = node.Title
}
return fmt.Sprintf("%s (external)", idStr)
}
// Color the ID based on status
var idStr string
switch node.Status {