From 00e90a447f990aca917116699f59202ffb9693b0 Mon Sep 17 00:00:00 2001 From: sumansaurabh Date: Tue, 27 May 2025 13:19:31 +0530 Subject: [PATCH 1/2] refactor(ui_utils.py): Simplify and consolidate message formatting functions --- penify_hook/api_client.py | 19 ++++++---- penify_hook/commands/auth_commands.py | 38 ++++++++++++------- penify_hook/commands/doc_commands.py | 16 -------- penify_hook/commit_analyzer.py | 53 +++------------------------ penify_hook/config_command.py | 14 +------ penify_hook/constants.py | 2 +- penify_hook/file_analyzer.py | 1 + 7 files changed, 45 insertions(+), 98 deletions(-) diff --git a/penify_hook/api_client.py b/penify_hook/api_client.py index 903e529..04e500d 100644 --- a/penify_hook/api_client.py +++ b/penify_hook/api_client.py @@ -75,15 +75,18 @@ def generate_commit_summary(self, git_diff, instruction: str = "", repo_details return None def get_supported_file_types(self) -> list[str]: + """Retrieve the supported file types from the API. - """Retrieve supported file types from the API or return a default list.""" - url = self.api_url+"/v1/cli/supported_languages" - response = requests.get(url) - if response.status_code == 200: - response = response.json() - return response - else: - return ["py", "js", "ts", "java", "kt", "cs", "c"] + This function sends a request to the API endpoint + `/v1/file/supported_languages` to obtain a list of supported file types. + If the API call is successful (status code 200), it parses the JSON + response and returns the list of supported file types. If the API call + fails, it returns a default list of common file types. + + Returns: + list[str]: A list of supported file types, either from the API or a default set. + """ + return ["py", "js", "ts", "java", "kt", "cs", "c", 'cpp', 'go', 'php', 'tsx','jsx'] def generate_commit_summary_with_llm(self, diff, message, generate_description: bool, repo_details, llm_client : LLMClient, jira_context=None): """Generates a commit summary using a local LLM client; falls back to API on diff --git a/penify_hook/commands/auth_commands.py b/penify_hook/commands/auth_commands.py index 5352d63..b156b7f 100644 --- a/penify_hook/commands/auth_commands.py +++ b/penify_hook/commands/auth_commands.py @@ -57,7 +57,7 @@ def save_credentials(api_key): f.write(f"{key}={value}\n") print(f"API token saved to {env_file}") - return True + # return True except Exception as e: print(f"Error saving to .env file: {str(e)}") # Fall back to saving in .penify global config @@ -92,10 +92,13 @@ def login(api_url, dashboard_url): redirect_port = random.randint(30000, 50000) redirect_url = f"http://localhost:{redirect_port}/callback" - full_login_url = f"{dashboard_url}?redirectUri={urllib.parse.quote(redirect_url)}" + full_login_url = f"{dashboard_url}?redirectUri={urllib.parse.quote(redirect_url)}&autoClose=true" print(f"Opening login page in your default web browser: {full_login_url}") - webbrowser.open(full_login_url) + # Open browser with autoraise=True to ensure window is brought to front + # Note: window.close() in JavaScript can only close windows that were opened by JavaScript + # We'll pass an autoClose parameter to the dashboard URL so the server can handle closing + webbrowser.open(full_login_url, autoraise=True) class TokenHandler(http.server.SimpleHTTPRequestHandler): def do_GET(self): @@ -113,15 +116,17 @@ def do_GET(self): response = """ - +

Login Successful!

-

You will be redirected to the Penify dashboard in 5 seconds. You can also close this window and return to the CLI.

+

API keys have been fetched and saved.

+

You can close this window and return to the CLI.

+

(The browser window cannot be closed automatically for security reasons)

""" @@ -133,7 +138,7 @@ def do_GET(self): if api_key: save_credentials(api_key) print("API keys fetched and saved successfully.") - print("You'll be redirected to the Penify dashboard. You can continue using the CLI.") + print("Please close the browser window and continue using the CLI.") else: print("Failed to fetch API keys.") else: @@ -142,9 +147,17 @@ def do_GET(self): self.end_headers() response = """ + + + -

Login Failed

-

Please try again.

+

Login Failed

+

Please try again.

+

You can close this window and return to the CLI.

""" @@ -155,7 +168,6 @@ def do_GET(self): thread = Thread(target=self.server.shutdown) thread.daemon = True thread.start() - def log_message(self, format, *args): # Suppress log messages """Suppress log messages.""" diff --git a/penify_hook/commands/doc_commands.py b/penify_hook/commands/doc_commands.py index 19661d0..66edc9a 100644 --- a/penify_hook/commands/doc_commands.py +++ b/penify_hook/commands/doc_commands.py @@ -22,22 +22,6 @@ def generate_doc(api_url, token, location=None): """ t1 = time.time() from ..api_client import APIClient - print(f"Time taken to laod APIClinet: {time.time() - t1:.2f} seconds") - """Generates documentation based on the given parameters. - - This function initializes an API client using the provided API URL and - token. It then generates documentation by analyzing the specified - location, which can be a folder, a file, or the current working - directory if no location is provided. The function handles different - types of analysis based on the input location and reports any errors - encountered during the process. - - Args: - api_url (str): The URL of the API to connect to for documentation generation. - token (str): The authentication token for accessing the API. - location (str?): The path to a specific file or folder to analyze. - If not provided, the current working directory is used. - """ api_client = APIClient(api_url, token) if location is None: current_folder_path = os.getcwd() diff --git a/penify_hook/commit_analyzer.py b/penify_hook/commit_analyzer.py index 4a5020c..6fe0d04 100644 --- a/penify_hook/commit_analyzer.py +++ b/penify_hook/commit_analyzer.py @@ -19,22 +19,7 @@ def __init__(self, repo_path: str, api_client: APIClient, llm_client=None, jira_ self.jira_client: JiraClient = jira_client # Add JIRA client as an optional parameter def get_summary(self, instruction: str, generate_description: bool) -> dict: - """Generate a summary for the commit based on the staged changes. - - This function retrieves the differences of the staged changes in the repository - and generates a commit summary using the provided instruction. If there are no - changes staged for commit, an exception is raised. If a JIRA client is - connected, it will attempt to extract issue keys from the current branch and - use them to fetch context. The summary can be generated either with a Language - Model (LLM) client or through the API client. - - Args: - instruction (str): A string containing instructions for generating the commit summary. - generate_description (bool): Whether to include detailed descriptions in the summary. - - Raises: - ValueError: If there are no changes staged for commit. - """ + """Generate a summary for the commit based on the staged changes.""" diff = self.repo.git.diff('--cached') if not diff: raise ValueError("No changes to commit") @@ -64,20 +49,8 @@ def get_summary(self, instruction: str, generate_description: bool) -> dict: def run(self, msg: Optional[str], edit_commit_message: bool, generate_description: bool): - """Run the post-commit hook. - - This method processes the modified files from the last commit, stages them, and - creates an auto-commit with an optional message. It also handles JIRA - integration if available. If there is an error generating the commit summary, - an exception is raised. - - Args: - msg (Optional[str]): An optional message to include in the commit. - edit_commit_message (bool): A flag indicating whether to open the git commit - edit terminal after committing. - generate_description (bool): A flag indicating whether to include a description - in the commit message. - """ + """Run the post-commit hook and create an auto-commit with optional JIRA + integration.""" summary: dict = self.get_summary(msg, True) if not summary: raise Exception("Error generating commit summary") @@ -102,23 +75,7 @@ def run(self, msg: Optional[str], edit_commit_message: bool, generate_descriptio def process_jira_integration(self, title: str, description: str, msg: str) -> tuple: # Look for JIRA issue keys in commit message, title, description and user message - """Process JIRA integration by extracting issue keys from commit message - components and branch name. - - This function looks for JIRA issue keys in the provided commit title, - description, original user message, and the active branch name. It uses these - keys to update the commit message with JIRA information and adds comments to - the corresponding JIRA issues. If no keys are found, it logs a warning. - - Args: - title (str): The generated commit title. - description (str): The generated commit description. - msg (str): The original user message that might contain JIRA references. - - Returns: - tuple: A tuple containing the updated commit title and description with included JIRA - information. - """ + """Process JIRA integration to update commit message with issue keys.""" issue_keys = [] if self.jira_client: # Extract from message content @@ -156,7 +113,7 @@ def process_jira_integration(self, title: str, description: str, msg: str) -> tu return title, description def _amend_commit(self): - """Amends the last commit message in the repository.""" + """Open the default git editor to amend the last commit message.""" try: # Change to the repository directory os.chdir(self.repo_path) diff --git a/penify_hook/config_command.py b/penify_hook/config_command.py index 281e698..a166585 100644 --- a/penify_hook/config_command.py +++ b/penify_hook/config_command.py @@ -4,7 +4,7 @@ def setup_config_parser(parent_parser): # Config subcommand: Create subparsers for config types - """Set up configuration parsers with subcommands for LLM and JIRA settings.""" + """Set up configuration parsers for different types of configurations.""" parser = parent_parser.add_subparsers(title="config_type", dest="config_type") # Config subcommand: llm @@ -34,17 +34,7 @@ def handle_config(args): - """Handle configuration settings based on the specified config type. - - This function processes different types of configurations such as LLM (Language - Model) and JIRA. It saves configurations, sets up web-based configurations, and - verifies JIRA connections. Depending on the `args.config_type`, it imports - necessary modules, handles configuration saving or setup, and optionally - verifies JIRA connectivity. - - Args: - args (argparse.Namespace): Command-line arguments containing the type of configuration to handle. - """ + """Handle configuration settings based on the specified config type.""" if args.config_type == "llm-cmd": from penify_hook.commands.config_commands import save_llm_config save_llm_config(args.model, args.api_base, args.api_key) diff --git a/penify_hook/constants.py b/penify_hook/constants.py index d00c2a8..45eab25 100644 --- a/penify_hook/constants.py +++ b/penify_hook/constants.py @@ -1,2 +1,2 @@ API_URL = 'http://localhost:8000/api' -DASHBOARD_URL = "https://dashboard.penify.dev/auth/localhost/login" \ No newline at end of file +DASHBOARD_URL = "http://localhost:8000/auth/localhost/login" \ No newline at end of file diff --git a/penify_hook/file_analyzer.py b/penify_hook/file_analyzer.py index 8ee49fa..363b87d 100644 --- a/penify_hook/file_analyzer.py +++ b/penify_hook/file_analyzer.py @@ -115,6 +115,7 @@ def run(self): """ stages = ["Validating", "Reading content", "Documenting", "Writing changes", "Completed"] pbar, _ = create_stage_progress_bar(stages, f"Starting documenting") + logger.debug(f"Processing file: {self.file_path}") try: # Print a clear indication of which file is being processed From 551cf2d02a1fef638474125cecbfbdc7203cc717 Mon Sep 17 00:00:00 2001 From: sumansaurabh Date: Tue, 27 May 2025 13:25:46 +0530 Subject: [PATCH 2/2] fix(constants.py): Update API and dashboard URLs for production environment --- penify_hook/constants.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/penify_hook/constants.py b/penify_hook/constants.py index 45eab25..082b8aa 100644 --- a/penify_hook/constants.py +++ b/penify_hook/constants.py @@ -1,2 +1,2 @@ -API_URL = 'http://localhost:8000/api' -DASHBOARD_URL = "http://localhost:8000/auth/localhost/login" \ No newline at end of file +API_URL = 'https://production.gateway.snorkell.ai/api' +DASHBOARD_URL = "https://dashboard.penify.dev/auth/localhost/login" \ No newline at end of file