@@ -695,6 +695,68 @@ def create_ai_bio_tab(self):
695695 ttk .Checkbutton (advanced_frame , text = "Show learning mindset (important for recent graduates)" ,
696696 variable = self .ai_show_learning_mindset ).pack (anchor = 'w' )
697697
698+ # README Selection Frame (NEW)
699+ readme_frame = ttk .LabelFrame (ai_bio_frame , text = "📄 README Files (Enhance Bio Context)" , padding = 15 )
700+ readme_frame .pack (fill = 'x' , padx = 20 , pady = (0 , 10 ))
701+
702+ # README selection explanation
703+ ttk .Label (readme_frame , text = "Select README files to analyze for project descriptions and achievements:" ,
704+ font = ('Segoe UI' , 9 )).pack (anchor = 'w' , pady = (0 , 5 ))
705+
706+ # README list with checkboxes
707+ readme_list_frame = ttk .Frame (readme_frame )
708+ readme_list_frame .pack (fill = 'both' , expand = True , pady = (0 , 10 ))
709+
710+ # Scrollable frame for README checkboxes
711+ self .readme_canvas = tk .Canvas (readme_list_frame , height = 100 )
712+ readme_scrollbar = ttk .Scrollbar (readme_list_frame , orient = "vertical" , command = self .readme_canvas .yview )
713+ self .readme_scrollable_frame = ttk .Frame (self .readme_canvas )
714+
715+ self .readme_scrollable_frame .bind (
716+ "<Configure>" ,
717+ lambda e : self .readme_canvas .configure (scrollregion = self .readme_canvas .bbox ("all" ))
718+ )
719+
720+ self .readme_canvas .create_window ((0 , 0 ), window = self .readme_scrollable_frame , anchor = "nw" )
721+ self .readme_canvas .configure (yscrollcommand = readme_scrollbar .set )
722+
723+ self .readme_canvas .pack (side = "left" , fill = "both" , expand = True )
724+ readme_scrollbar .pack (side = "right" , fill = "y" )
725+
726+ # Store README checkboxes
727+ self .readme_checkboxes = {}
728+
729+ # README controls
730+ readme_controls = ttk .Frame (readme_frame )
731+ readme_controls .pack (fill = 'x' , pady = (5 , 0 ))
732+
733+ ttk .Button (readme_controls , text = "Select All" , command = self .select_all_readmes ).pack (side = 'left' , padx = (0 , 5 ))
734+ ttk .Button (readme_controls , text = "Clear All" , command = self .clear_all_readmes ).pack (side = 'left' , padx = 5 )
735+ ttk .Button (readme_controls , text = "Refresh List" , command = self .refresh_readme_list ).pack (side = 'left' , padx = 5 )
736+
737+ # Website Links Frame (NEW)
738+ websites_frame = ttk .LabelFrame (ai_bio_frame , text = "🌐 Website Links (Professional Presence)" , padding = 15 )
739+ websites_frame .pack (fill = 'x' , padx = 20 , pady = (0 , 10 ))
740+
741+ # Website inputs
742+ website_grid = ttk .Frame (websites_frame )
743+ website_grid .pack (fill = 'x' )
744+
745+ # Portfolio website
746+ ttk .Label (website_grid , text = "Portfolio Website:" , font = ('Segoe UI' , 9 , 'bold' )).grid (row = 0 , column = 0 , sticky = 'w' , padx = (0 , 10 ), pady = (5 , 2 ))
747+ self .portfolio_url = ttk .Entry (website_grid , width = 50 )
748+ self .portfolio_url .grid (row = 0 , column = 1 , sticky = 'ew' , padx = (0 , 10 ), pady = (5 , 2 ))
749+ ttk .Label (website_grid , text = "(e.g., https://yourname.dev)" , font = ('Segoe UI' , 8 ), foreground = 'gray' ).grid (row = 0 , column = 2 , sticky = 'w' , pady = (5 , 2 ))
750+
751+ # Professional website/company
752+ ttk .Label (website_grid , text = "Professional Website:" , font = ('Segoe UI' , 9 , 'bold' )).grid (row = 1 , column = 0 , sticky = 'w' , padx = (0 , 10 ), pady = (5 , 2 ))
753+ self .professional_url = ttk .Entry (website_grid , width = 50 )
754+ self .professional_url .grid (row = 1 , column = 1 , sticky = 'ew' , padx = (0 , 10 ), pady = (5 , 2 ))
755+ ttk .Label (website_grid , text = "(e.g., company website, personal brand)" , font = ('Segoe UI' , 8 ), foreground = 'gray' ).grid (row = 1 , column = 2 , sticky = 'w' , pady = (5 , 2 ))
756+
757+ # Configure grid weights
758+ website_grid .columnconfigure (1 , weight = 1 )
759+
698760 # OpenRouter AI Enhancement
699761 openrouter_frame = ttk .LabelFrame (ai_bio_frame , text = "🤖 OpenRouter AI Enhancement" , padding = 15 )
700762 openrouter_frame .pack (fill = 'x' , padx = 20 , pady = (0 , 10 ))
@@ -1081,6 +1143,10 @@ def _fetch_completed(self, user_data: GitHubUserData):
10811143 # Update README combo
10821144 self ._update_readme_combo ()
10831145
1146+ # Refresh README selection list for AI Bio tab
1147+ if hasattr (self , 'refresh_readme_list' ):
1148+ self .refresh_readme_list ()
1149+
10841150 # Switch to scan tab
10851151 self .notebook .select (1 )
10861152
@@ -1895,6 +1961,30 @@ def _generate_ai_bio_thread(self):
18951961 config .frameworks_libraries = [fw .strip () for fw in self .ai_frameworks_libraries .get ('1.0' , tk .END ).strip ().split (',' ) if fw .strip ()]
18961962 config .tools_platforms = [tool .strip () for tool in self .ai_tools_platforms .get ('1.0' , tk .END ).strip ().split (',' ) if tool .strip ()]
18971963
1964+ # Get selected README files and website links (NEW)
1965+ selected_readmes = self .get_selected_readmes ()
1966+ portfolio_url = self .portfolio_url .get ().strip ()
1967+ professional_url = self .professional_url .get ().strip ()
1968+
1969+ # Add to config if available
1970+ if hasattr (config , 'selected_readmes' ):
1971+ config .selected_readmes = selected_readmes
1972+ else :
1973+ config .selected_readmes = selected_readmes
1974+
1975+ if hasattr (config , 'portfolio_website' ):
1976+ config .portfolio_website = portfolio_url
1977+ else :
1978+ config .portfolio_website = portfolio_url
1979+
1980+ if hasattr (config , 'professional_website' ):
1981+ config .professional_website = professional_url
1982+ else :
1983+ config .professional_website = professional_url
1984+
1985+ self .logger .info (f"AI Bio Config: { config .experience_level } , { len (config .programming_languages )} languages, { len (selected_readmes )} READMEs" )
1986+ self .logger .info (f"Websites: Portfolio={ bool (portfolio_url )} , Professional={ bool (professional_url )} " )
1987+
18981988 # Initialize AI bio generator
18991989 ai_bio_generator = AILinkedInBioGenerator (config )
19001990
@@ -3589,6 +3679,104 @@ def clear_tech_fields(self):
35893679 self .ai_frameworks_libraries .delete ('1.0' , tk .END )
35903680 self .ai_tools_platforms .delete ('1.0' , tk .END )
35913681
3682+ def refresh_readme_list (self ):
3683+ """Refresh the list of available README files from repositories."""
3684+ # Clear existing checkboxes
3685+ for widget in self .readme_scrollable_frame .winfo_children ():
3686+ widget .destroy ()
3687+ self .readme_checkboxes .clear ()
3688+
3689+ if not self .current_user_data or not self .current_user_data .repositories :
3690+ ttk .Label (self .readme_scrollable_frame , text = "No repositories loaded. Please fetch GitHub data first." ,
3691+ foreground = 'gray' ).pack (pady = 10 )
3692+ return
3693+
3694+ # Add checkboxes for each repository with README
3695+ row = 0
3696+ for repo in self .current_user_data .repositories :
3697+ if not repo .is_fork : # Only show original repositories
3698+ var = tk .BooleanVar (value = True ) # Default to selected
3699+ self .readme_checkboxes [repo .name ] = var
3700+
3701+ checkbox = ttk .Checkbutton (
3702+ self .readme_scrollable_frame ,
3703+ text = f"{ repo .name } ({ repo .language or 'Unknown' } ) - { repo .stars } ⭐" ,
3704+ variable = var
3705+ )
3706+ checkbox .grid (row = row , column = 0 , sticky = 'w' , padx = 5 , pady = 2 )
3707+ row += 1
3708+
3709+ if row == 0 :
3710+ ttk .Label (self .readme_scrollable_frame , text = "No original repositories found." ,
3711+ foreground = 'gray' ).pack (pady = 10 )
3712+
3713+ def select_all_readmes (self ):
3714+ """Select all README checkboxes."""
3715+ for var in self .readme_checkboxes .values ():
3716+ var .set (True )
3717+
3718+ def clear_all_readmes (self ):
3719+ """Clear all README checkboxes."""
3720+ for var in self .readme_checkboxes .values ():
3721+ var .set (False )
3722+
3723+ def get_selected_readmes (self ):
3724+ """Get list of selected repository names for README analysis."""
3725+ selected = []
3726+ for repo_name , var in self .readme_checkboxes .items ():
3727+ if var .get ():
3728+ selected .append (repo_name )
3729+ return selected
3730+
3731+ def refresh_readme_list (self ):
3732+ """Refresh the list of available README files from repositories."""
3733+ # Clear existing checkboxes
3734+ for widget in self .readme_scrollable_frame .winfo_children ():
3735+ widget .destroy ()
3736+ self .readme_checkboxes .clear ()
3737+
3738+ if not self .current_user_data or not self .current_user_data .repositories :
3739+ ttk .Label (self .readme_scrollable_frame , text = "No repositories loaded. Please fetch GitHub data first." ,
3740+ foreground = 'gray' ).pack (pady = 10 )
3741+ return
3742+
3743+ # Add checkboxes for each repository with README
3744+ row = 0
3745+ for repo in self .current_user_data .repositories :
3746+ if not repo .is_fork : # Only show original repositories
3747+ var = tk .BooleanVar (value = True ) # Default to selected
3748+ self .readme_checkboxes [repo .name ] = var
3749+
3750+ checkbox = ttk .Checkbutton (
3751+ self .readme_scrollable_frame ,
3752+ text = f"{ repo .name } ({ repo .language or 'Unknown' } ) - { repo .stars } ⭐" ,
3753+ variable = var
3754+ )
3755+ checkbox .grid (row = row , column = 0 , sticky = 'w' , padx = 5 , pady = 2 )
3756+ row += 1
3757+
3758+ if row == 0 :
3759+ ttk .Label (self .readme_scrollable_frame , text = "No original repositories found." ,
3760+ foreground = 'gray' ).pack (pady = 10 )
3761+
3762+ def select_all_readmes (self ):
3763+ """Select all README checkboxes."""
3764+ for var in self .readme_checkboxes .values ():
3765+ var .set (True )
3766+
3767+ def clear_all_readmes (self ):
3768+ """Clear all README checkboxes."""
3769+ for var in self .readme_checkboxes .values ():
3770+ var .set (False )
3771+
3772+ def get_selected_readmes (self ):
3773+ """Get list of selected repository names for README analysis."""
3774+ selected = []
3775+ for repo_name , var in self .readme_checkboxes .items ():
3776+ if var .get ():
3777+ selected .append (repo_name )
3778+ return selected
3779+
35923780 def run (self ):
35933781 """Start the GUI application."""
35943782 try :
0 commit comments