| 926 | } |
| 927 | |
| 928 | func handleGetFileContext(ctx context.Context, req *mcp.CallToolRequest, input ImportersInput) (*mcp.CallToolResult, any, error) { |
| 929 | fg, err := scanner.BuildFileGraph(input.Path) |
| 930 | if err != nil { |
| 931 | return errorResult("Failed to build file graph: " + err.Error()), nil, nil |
| 932 | } |
| 933 | |
| 934 | file := input.File |
| 935 | imports := fg.Imports[file] |
| 936 | importers := fg.Importers[file] |
| 937 | isHub := fg.IsHub(file) |
| 938 | connected := fg.ConnectedFiles(file) |
| 939 | |
| 940 | var sb strings.Builder |
| 941 | sb.WriteString(fmt.Sprintf("=== File Context: %s ===\n\n", file)) |
| 942 | |
| 943 | // Hub status |
| 944 | if isHub { |
| 945 | sb.WriteString(fmt.Sprintf("⚠️ HUB FILE - %d files depend on this\n", len(importers))) |
| 946 | sb.WriteString(" Changes here affect many parts of the codebase.\n\n") |
| 947 | } |
| 948 | |
| 949 | // What this file imports |
| 950 | if len(imports) > 0 { |
| 951 | sb.WriteString(fmt.Sprintf("IMPORTS (%d files):\n", len(imports))) |
| 952 | for _, imp := range imports { |
| 953 | sb.WriteString(fmt.Sprintf(" -> %s\n", imp)) |
| 954 | } |
| 955 | sb.WriteString("\n") |
| 956 | } else { |
| 957 | sb.WriteString("IMPORTS: none (leaf file)\n\n") |
| 958 | } |
| 959 | |
| 960 | // What imports this file |
| 961 | if len(importers) > 0 { |
| 962 | sb.WriteString(fmt.Sprintf("IMPORTED BY (%d files):\n", len(importers))) |
| 963 | for _, imp := range importers { |
| 964 | sb.WriteString(fmt.Sprintf(" <- %s\n", imp)) |
| 965 | } |
| 966 | sb.WriteString("\n") |
| 967 | } else { |
| 968 | sb.WriteString("IMPORTED BY: none (entry point or unused)\n\n") |
| 969 | } |
| 970 | |
| 971 | // Connected files summary |
| 972 | sb.WriteString(fmt.Sprintf("CONNECTED: %d files in dependency graph\n", len(connected))) |
| 973 | |
| 974 | return textResult(sb.String()), nil, nil |
| 975 | } |
| 976 | |
| 977 | // handleGetWorkingSet returns the current session's working set |
| 978 | func handleGetWorkingSet(ctx context.Context, req *mcp.CallToolRequest, input WatchInput) (*mcp.CallToolResult, any, error) { |