From b46bf5401e5b13ab3d105db57353a93bea6e0649 Mon Sep 17 00:00:00 2001 From: Mohammad Faiz Date: Wed, 22 Jul 2026 23:07:07 +0530 Subject: [PATCH 1/3] Add .gitignore and fix bugs in app, config, and docs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This update makes several fixes across the project: 1. Add .gitignore — stops Python cache files (__pycache__), virtual environments, IDE settings, OS files, and user credentials from being uploaded to GitHub. Keeps the repository clean and secure. 2. Fix app.py — removed unused 'threading' import to make code cleaner. Fixed mouse hover effects in buttons (PulseBtn, GhostBtn, NavBtn) so they work correctly. Removed outdated comments from voice input function. 3. Fix app_config.json — corrected a typo in the field name 'annon_key' to 'anon_key' so the Supabase connection works. 4. Fix mcp_link.py — config loading now tries three places in order: the user's local file, the bundled app_config.json, then GitHub. Fixed the key names to match the actual config file format. Removed unused 'import os'. 5. Fix requirements.txt — added 'cryptography' and 'requests' as dependencies so the app does not crash when starting up. 6. Fix run command in docs — corrected both README.md and Docs.md from 'python main.py' (which doesn't exist) to the correct 'python Desktop_App/app.py'. 7. Remove empty file — deleted Docs/app.py which was blank and served no purpose. --- .gitignore | 38 ++++++++++++++++++++++++++++++++++++ Desktop_App/app.py | 20 ++++++++----------- Desktop_App/app_config.json | 2 +- Desktop_App/mcp_link.py | 19 ++++++++++++++---- Desktop_App/requirements.txt | 2 ++ Docs/Docs.md | 2 +- Docs/app.py | 1 - README.md | 2 +- 8 files changed, 66 insertions(+), 20 deletions(-) create mode 100644 .gitignore delete mode 100644 Docs/app.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c61ceb4 --- /dev/null +++ b/.gitignore @@ -0,0 +1,38 @@ +# Python +__pycache__/ +*.py[cod] +*.pyo +*.egg-info/ +dist/ +build/ +*.egg +*.whl + +# Virtual environments +venv/ +.venv/ +env/ +.env/ + +# IDE +.vscode/ +.idea/ +*.swp +*.swo +*~ + +# OS +.DS_Store +Thumbs.db + +# User config & credentials +.npmai_agent/ +Desktop_App/app_config.json + +# Build artifacts +*.exe +*.zip +*.dmg + +# Logs +*.log diff --git a/Desktop_App/app.py b/Desktop_App/app.py index a74c7e5..3de7e10 100644 --- a/Desktop_App/app.py +++ b/Desktop_App/app.py @@ -5,7 +5,7 @@ THIS IS NOT YET DEPLOYED. Here it is about Desktop APP. """ -import sys, os, math, random, threading, json +import sys, os, math, random, json from pathlib import Path sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) @@ -77,7 +77,7 @@ def _load_llm_stage_config() -> dict: cfg = {} for stage_key, _, _ in AGENT_STAGES: - if stage_key not in cfg: # ← only this line changed + if stage_key not in cfg: cfg[stage_key] = { "provider": "npmai", "model": LLM_PROVIDERS["npmai"]["model_default"] @@ -315,8 +315,8 @@ def _tick(self): if self._pulse<=0: self._pd=1 self.update() - def enterEvent(self,e): self._h=1.0 - def leaveEvent(self,e): self._h=0.0 + def enterEvent(self,e): self._h=1.0; super().enterEvent(e) + def leaveEvent(self,e): self._h=0.0; super().leaveEvent(e) def mousePressEvent(self,e): self._press=True; super().mousePressEvent(e) def mouseReleaseEvent(self,e): self._press=False; super().mouseReleaseEvent(e) @@ -345,8 +345,8 @@ def __init__(self,text,accent="#2AFFA0",parent=None): self.setFont(QFont("Segoe UI",11,QFont.DemiBold)) QTimer(self,timeout=self.update,interval=16).start() - def enterEvent(self,e): self._h=1.0 - def leaveEvent(self,e): self._h=0.0 + def enterEvent(self,e): self._h=1.0; super().enterEvent(e) + def leaveEvent(self,e): self._h=0.0; super().leaveEvent(e) def paintEvent(self,_): p=QPainter(self); p.setRenderHint(QPainter.Antialiasing) @@ -456,8 +456,8 @@ def _tick(self): self._h+=(t-self._h)*0.1; self.update() def set_active(self,v): self._active=v; self.update() - def enterEvent(self,e): self._hf=True - def leaveEvent(self,e): self._hf=False + def enterEvent(self,e): self._hf=True; super().enterEvent(e) + def leaveEvent(self,e): self._hf=False; super().leaveEvent(e) def mousePressEvent(self,e): self.clicked.emit(self._idx) def paintEvent(self,_): @@ -893,10 +893,6 @@ def _log(self, html:str): self._log_box.verticalScrollBar().setValue(self._log_box.verticalScrollBar().maximum()) def _voice_input(self): - """ If you are working with voice input kindly read the documentation of npmai_agents and this code uses - npmai_agents version 1.0.2, npmai_agents change frequently although not syntax but it will be better to read - before making any change.""" - """ old VoiceTool.listen(): SpeechAITool.transcribe_realtime """ from npmai_agents.Tools_security_ai import SpeechAITool r = SpeechAITool.transcribe_realtime(duration=5) if r.success and r.data: diff --git a/Desktop_App/app_config.json b/Desktop_App/app_config.json index fe3d1d8..efb9c7e 100644 --- a/Desktop_App/app_config.json +++ b/Desktop_App/app_config.json @@ -1,5 +1,5 @@ { "url": "https://qyxuvuhhaspkuhbognyk.supabase.co", - "annon_key": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InF5eHV2dWhoYXNwa3VoYm9nbnlrIiwicm9sZSI6ImFub24iLCJpYXQiOjE3ODQ3MDYwNzYsImV4cCI6MjEwMDI4MjA3Nn0.h3hyVr_OV38SfY2_2qQ6Hgtm6_FbvNQ31AG5YO7mVko", + "anon_key": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InF5eHV2dWhoYXNwa3VoYm9nbnlrIiwicm9sZSI6ImFub24iLCJpYXQiOjE3ODQ3MDYwNzYsImV4cCI6MjEwMDI4MjA3Nn0.h3hyVr_OV38SfY2_2qQ6Hgtm6_FbvNQ31AG5YO7mVko", "mcp_base_url": "https://your-mcp-server.hf.space/mcp" } diff --git a/Desktop_App/mcp_link.py b/Desktop_App/mcp_link.py index be23d74..8eca9d2 100644 --- a/Desktop_App/mcp_link.py +++ b/Desktop_App/mcp_link.py @@ -1,4 +1,3 @@ -import os import json import uuid import threading @@ -8,18 +7,30 @@ from typing import Callable, Optional CONFIG_PATH = Path.home() / ".npmai_agent" / "supabase_config.json" +BUNDLED_CONFIG_PATH = Path(__file__).resolve().parent / "app_config.json" CONFIG_URL = "https://raw.githubusercontent.com/npmaiecosystem/NPM-AutoCode-AI/refs/heads/main/Desktop_App/app_config.json" def load_config() -> dict: - """Fetch latest config from GitHub""" + """Load config from user override, then bundled file, then GitHub, then empty.""" + if CONFIG_PATH.exists(): + try: + return json.loads(CONFIG_PATH.read_text()) + except Exception as e: + print(f"Failed to read local config: {e}") + if BUNDLED_CONFIG_PATH.exists(): + try: + return json.loads(BUNDLED_CONFIG_PATH.read_text()) + except Exception as e: + print(f"Failed to read bundled config: {e}") try: response = requests.get(CONFIG_URL, timeout=8) if response.status_code == 200: return response.json() except Exception as e: print(f"Failed to fetch remote config: {e}") + return {} def save_config(url: str, anon_key: str, mcp_base_url: str = None): @@ -61,12 +72,12 @@ def _get_client(self): "The 'supabase' package isn't installed. Run: pip install supabase" ) cfg = load_config() - if not cfg.get("SUPABASE_URL") or not cfg.get("SUPABASE_ANNON_KEY"): + if not cfg.get("url") or not cfg.get("anon_key"): raise SupabaseAuthError( "Supabase isn't configured yet. Set SUPABASE_URL and SUPABASE_ANON_KEY " "env vars, or call mcp_link.save_config(url, anon_key) once from Settings." ) - self._client = create_client(cfg["SUPABASE_URL"], cfg["SUPABASE_ANNON_KEY"]) + self._client = create_client(cfg["url"], cfg["anon_key"]) return self._client def sign_up(self, email: str, password: str): diff --git a/Desktop_App/requirements.txt b/Desktop_App/requirements.txt index 8c420a1..25bd6c8 100644 --- a/Desktop_App/requirements.txt +++ b/Desktop_App/requirements.txt @@ -5,3 +5,5 @@ langchain-community npmai==0.1.9 npmai-agents==1.0.2 supabase +cryptography +requests diff --git a/Docs/Docs.md b/Docs/Docs.md index ae924c0..3c07c81 100644 --- a/Docs/Docs.md +++ b/Docs/Docs.md @@ -5,7 +5,7 @@ Install the app: [Download Latest Release](https://github.com/sonuramashishnpm/NPM-AutoCode-AI/releases/download/v2.0/NPM_AutoCode_AI.zip) 1. Unzip the file. -2. Run `NPM_AutoCode_AI.exe` (Windows) or `python main.py` (Python 3.12+). +2. Run `NPM_AutoCode_AI.exe` (Windows) or `python Desktop_App/app.py` (Python 3.12+). 3. Enter your task in the input box (e.g., "Plot a sine wave"). 4. Click **Generate & Execute**. 5. Watch logs and progress bar – AI generates, checks safety, executes, and fixes errors if needed. diff --git a/Docs/app.py b/Docs/app.py deleted file mode 100644 index 8b13789..0000000 --- a/Docs/app.py +++ /dev/null @@ -1 +0,0 @@ - diff --git a/README.md b/README.md index d76f6cf..136576b 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ Install the app: [Download Latest Release](https://github.com/sonuramashishnpm/NPM-AutoCode-AI/releases/download/v2.2/NPM_AutoCode_AI.zip) 1. Unzip the file. -2. Run `NPM_AutoCode_AI.exe` (Windows) or `python main.py` (Python 3.12+). +2. Run `NPM_AutoCode_AI.exe` (Windows) or `python Desktop_App/app.py` (Python 3.12+). 3. Enter your task in the input box (e.g., "Plot a sine wave"). 4. Click **Generate & Execute**. 5. Watch logs and progress bar – AI generates, checks safety, executes, and fixes errors if needed. From 26d30c2c2e57e03818788698ff4afbea18b8964e Mon Sep 17 00:00:00 2001 From: Mohammad Faiz Date: Wed, 22 Jul 2026 23:51:53 +0530 Subject: [PATCH 2/3] Address PR review: restore Docs/app.py, voice_input comments, simplify config loading MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Per maintainer review feedback: 1. Restored Docs/app.py (empty file) as requested. 2. Restored documentation comments above _voice_input() function. 3. Simplified load_config() in mcp_link.py — removed local user config override fallback. Now tries bundled app_config.json first, then GitHub fetch. Kept the key name fixes (url/anon_key) that match the actual JSON structure. --- Desktop_App/app.py | 4 ++++ Desktop_App/mcp_link.py | 17 ++++++----------- Docs/app.py | 1 + 3 files changed, 11 insertions(+), 11 deletions(-) create mode 100644 Docs/app.py diff --git a/Desktop_App/app.py b/Desktop_App/app.py index 3de7e10..4df2d8b 100644 --- a/Desktop_App/app.py +++ b/Desktop_App/app.py @@ -893,6 +893,10 @@ def _log(self, html:str): self._log_box.verticalScrollBar().setValue(self._log_box.verticalScrollBar().maximum()) def _voice_input(self): + """If you are working with voice input kindly read the documentation of npmai_agents and this code uses + npmai_agents version 1.0.2, npmai_agents change frequently although not syntax but it will be better to read + before making any change.""" + """ old VoiceTool.listen(): SpeechAITool.transcribe_realtime """ from npmai_agents.Tools_security_ai import SpeechAITool r = SpeechAITool.transcribe_realtime(duration=5) if r.success and r.data: diff --git a/Desktop_App/mcp_link.py b/Desktop_App/mcp_link.py index 8eca9d2..26c2d30 100644 --- a/Desktop_App/mcp_link.py +++ b/Desktop_App/mcp_link.py @@ -7,23 +7,18 @@ from typing import Callable, Optional CONFIG_PATH = Path.home() / ".npmai_agent" / "supabase_config.json" -BUNDLED_CONFIG_PATH = Path(__file__).resolve().parent / "app_config.json" CONFIG_URL = "https://raw.githubusercontent.com/npmaiecosystem/NPM-AutoCode-AI/refs/heads/main/Desktop_App/app_config.json" def load_config() -> dict: - """Load config from user override, then bundled file, then GitHub, then empty.""" - if CONFIG_PATH.exists(): + """Fetch latest config from GitHub (primary), fall back to bundled file.""" + bundled = Path(__file__).resolve().parent / "app_config.json" + if bundled.exists(): try: - return json.loads(CONFIG_PATH.read_text()) - except Exception as e: - print(f"Failed to read local config: {e}") - if BUNDLED_CONFIG_PATH.exists(): - try: - return json.loads(BUNDLED_CONFIG_PATH.read_text()) - except Exception as e: - print(f"Failed to read bundled config: {e}") + return json.loads(bundled.read_text()) + except Exception: + pass try: response = requests.get(CONFIG_URL, timeout=8) if response.status_code == 200: diff --git a/Docs/app.py b/Docs/app.py new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/Docs/app.py @@ -0,0 +1 @@ + From 83765c324ab337b9b4f35cf979ebcc3b82455752 Mon Sep 17 00:00:00 2001 From: Mohammad Faiz Date: Thu, 23 Jul 2026 00:10:31 +0530 Subject: [PATCH 3/3] Fix load_config order: GitHub first, then bundled fallback Per maintainer review: try GitHubUserContent first so the open-source org can push config updates centrally. Bundled app_config.json is only a fallback when offline. --- Desktop_App/mcp_link.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Desktop_App/mcp_link.py b/Desktop_App/mcp_link.py index 26c2d30..b89541f 100644 --- a/Desktop_App/mcp_link.py +++ b/Desktop_App/mcp_link.py @@ -13,18 +13,18 @@ def load_config() -> dict: """Fetch latest config from GitHub (primary), fall back to bundled file.""" - bundled = Path(__file__).resolve().parent / "app_config.json" - if bundled.exists(): - try: - return json.loads(bundled.read_text()) - except Exception: - pass try: response = requests.get(CONFIG_URL, timeout=8) if response.status_code == 200: return response.json() except Exception as e: print(f"Failed to fetch remote config: {e}") + bundled = Path(__file__).resolve().parent / "app_config.json" + if bundled.exists(): + try: + return json.loads(bundled.read_text()) + except Exception: + pass return {}